using System;
using System.IO;
using System.Text;
using ChatSocketService;

namespace SmartBoard.Core.Server
{
    public class ServerMessageBuilder:IServerMessageBuilder
    {
        #region Private Fields
        private readonly byte[] _messageInitBytes;
        private readonly byte[] _messageEndBytes;
        #endregion

        #region Ctor
        public ServerMessageBuilder()
        {
            _messageInitBytes = Encoding.ASCII.GetBytes("-");
            _messageEndBytes = Encoding.ASCII.GetBytes("-");
        }
        #endregion

        #region IServerMessageBuilder Members

        public IServerMessage GetServerMessage(byte[] buffer)
        {
            var moduleId = -1;
            var messageId = -1;

            var offset = _messageInitBytes.Length;
            moduleId = buffer[offset++];

            messageId = BitConverter.ToInt32(buffer, offset);
            offset += 4;

            var payloadLength = BitConverter.ToInt32(buffer, offset);
            offset += 4;

            var payload = new byte[payloadLength];
            Array.Copy(buffer, offset, payload, 0, payloadLength);

            return new ServerMessage((byte)moduleId, messageId, payload);
        }

        public byte[] GetRawBuffer(IServerMessage message)
        {
            using (var stream = new MemoryStream())
            {
                // Every stream should start from this.
                stream.Write(_messageInitBytes, 0, _messageInitBytes.Length);

                //Write the ModuleId
                stream.WriteByte(message.MessageTargetModuleId);

                //Write the message Id
                var messageIdBytes = BitConverter.GetBytes(message.MessageId);
                stream.Write(messageIdBytes,0,messageIdBytes.Length);

                //Write the payload Length
                var payloadlength = BitConverter.GetBytes(message.Payload.Length);
                stream.Write(payloadlength, 0, payloadlength.Length);

                //Write the payload
                stream.Write(message.Payload, 0, message.Payload.Length);

                stream.Write(_messageEndBytes, 0, _messageEndBytes.Length);
                stream.Flush();

                // return the array for stream.
                return stream.ToArray();
            }
        }

        #endregion
    }
}